﻿//单向链表库
//copyright (c) 2016 L.W.C.<lwc@li.cm>

#include "vxin_slist.h"

vxin_slist* SLIST_New(void* ptr,uint id){
	vxin_slist *r;
	r=vxin_malloc(sizeof(vxin_slist));
	r->ptr=ptr;
	r->id=id;
	r->next=0;
	return r;
}

void SLIST_Destroy(vxin_slist* slist){
	vxin_slist* tmp;
	while(slist){
		tmp=slist->next;   //呵呵呵
		vxin_free(slist);
		slist=tmp;
	}
}

vxin_slist* SLIST_GetById(vxin_slist *slist,uint id){  //返回找到的第一个
	while(slist->next&&slist->id!=id){
		slist=slist->next;
	}
	return (slist->id==id)?slist:0;
}

vxin_slist* SLIST_GetByPtr(vxin_slist *slist,void* ptr,int (*fun)(void*ptrA,void*ptrB)){//返回找到的第一个
	while(slist->next&&!fun(slist->ptr,ptr)){
		slist=slist->next;
	}
	return (fun(slist->ptr,ptr))?slist:0;
}

vxin_slist* SLIST_GetByIndex(vxin_slist *slist,uint index){
	while(slist->next&&index--){ /*模拟递归（递归稍有危险，此方法更安全）*/
		slist=slist->next;
	}
	return slist->next?slist:0;
}

vxin_slist* SLIST_Push(vxin_slist *slist,void* ptr,uint id){
	vxin_slist *r;
	r=vxin_malloc(sizeof(vxin_slist));
	//复制第一节
	r->ptr=slist->ptr;
	r->id=slist->id;
	r->next=slist->next;
	//将第一节数据改为新添加的数据并使r为第二节
	slist->ptr=ptr; 
	slist->id=id;
	slist->next=r;
	return r;
}

/*请勿弹出最后一节*/
vxin_slist* SLIST_Pop(vxin_slist *slist,void** ptr,uint* id){
	//此方法可保留原地址不变进行弹出
	vxin_slist *tmp;
	if(ptr)*ptr=slist->ptr;   //写入数据到变量
	if(id)*id=slist->id;
	if(!slist->next){
		return slist;
	}
	slist->ptr=slist->next->ptr;  //使第一节变为第二节
	slist->id=slist->next->id;
	tmp=slist->next;                  //保存第二节地址
	slist->next=slist->next->next;   //第一节下一位地址改为第二节下一位地址
	vxin_free(tmp);  //删除第二节
	return slist;
}

vxin_slist* SLIST_GetEnd(vxin_slist *slist){
	while(slist->next){  //比递归安全
		slist=slist->next;
	}
	return slist;
}